﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace DMS.Business.Utility
{
    public static class DataTypeConverter
    {
        /// <summary>
        /// Convert.ChangeType doesnot support Nullable
        /// </summary>
        /// <param name="value"></param>
        /// <param name="conversionType"></param>
        /// <returns></returns>
        public static object ChangeType(this object value, Type conversionType)
        {
            if ((value == null) && conversionType.IsGenericType)
            {
                return Activator.CreateInstance(conversionType);
            }
            if (value == null)
            {
                return null;
            }
            if (conversionType == value.GetType())
            {
                return value;
            }

            if (conversionType.IsEnum)
            {
                if (value is string)
                {
                    return Enum.Parse(conversionType, value as string);
                }
                return Enum.ToObject(conversionType, value);
            }

            if (!conversionType.IsInterface && conversionType.IsGenericType)
            {
                Type type1 = conversionType.GetGenericArguments()[0];
                object obj1 = value.ChangeType(type1);
                return Activator.CreateInstance(conversionType, new object[] {obj1});
            }

            if ((value is string) && (conversionType == typeof (Guid)))
            {
                return new Guid(value as string);
            }

            if ((value is string) && (conversionType == typeof (Version)))
            {
                return new Version(value as string);
            }

            if (!(value is IConvertible))
            {
                return value;
            }

            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof (Nullable<>)))
            {
                var nullableConverter = new NullableConverter(conversionType);
                conversionType = nullableConverter.UnderlyingType;
                return null;
            }

            return Convert.ChangeType(value, conversionType);
        }

    }
}
